﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Globalization;

namespace Data.AID
{
    public class Formulario
    {
        public int Id { get; set; }
        public string Matricula { get; set; }
        public string Nome { get; set; }
        public string Funcao { get; set; }
        public string Area { get; set; }
        public DateTime DtAdmissao { get; set; }
        public string GestorImediato { get; set; }
        public DateTime Criado { get; set; }
        public string CriadoPor { get; set; }
        public int Estagio { get; set; }
        public string EstagioDesc { get; set; }
        public Boolean AprovacaoGestor { get; set; }
        public Boolean AprovacaoAuditoria { get; set; } 
        public DateTime Modificado { get; set; }
        public string ModificadoPor { get; set; }
        public int IdColaborador { get; set; }
        public string AttachmentName { get; set; }
        public string AttachmentUrl { get; set; }
        public int NumeroFormulario { get; set; }
    }

    public class FormularioDAO
    {
        public string ListaFormulario
        {
            get { return "Formulario"; }
        }

        private SPSite Site = SPContext.Current.Site;
        private SPWeb Web = SPContext.Current.Web;

        /// <summary>
        /// Recupera todos os formulários.
        /// </summary>
        /// <returns></returns>
        public List<Formulario> GetAllForms()
        {
            try
            {
                using (SPSite eSite = new SPSite(Site.ID))
                {
                    using (SPWeb eWeb = eSite.OpenWeb(Web.ID))
                    {
                        IFormatProvider provider = CultureInfo.InvariantCulture;

                        List<Colaborador> ColaboradorLista = new ColaboradorDAO().GettAllEmployees();

                        List<Formulario> FormularioLista = eWeb.Lists[ListaFormulario].Items.Cast<SPListItem>()
                                    .Select(p => new Formulario
                                    {
                                        Id = Convert.ToInt32(p["ID"]),
                                        Criado = Convert.ToDateTime(p["Criado"]),
                                        CriadoPor = p["Criado por"].ToString(),
                                        AprovacaoAuditoria = Convert.ToBoolean(p["AprovacaoAuditoria"]),
                                        AprovacaoGestor = Convert.ToBoolean(p["AprovacaoGestor"]),
                                        Modificado = Convert.ToDateTime(p["Modificado"]),
                                        ModificadoPor = p["Modificado por"].ToString(),
                                        Estagio =  new SPFieldLookupValue(p["Estagio"].ToString()).LookupId,
                                        EstagioDesc = new SPFieldLookupValue(p["Estagio"].ToString()).LookupValue,
                                        IdColaborador = Convert.ToInt32(p["IdColaborador"]),
                                        AttachmentUrl = p["AttachmentName"] == null ? "" : p.Attachments.UrlPrefix + p["AttachmentName"].ToString(),
                                        AttachmentName = p["AttachmentName"] == null ? "" : p["AttachmentName"].ToString(),
                                        NumeroFormulario = p["NumeroFormulario"] == null ? 0 : Convert.ToInt32(p["NumeroFormulario"])
                                    }).ToList();

                        List<Formulario> query = (from c in ColaboradorLista
                                                  join f in FormularioLista on c.Id equals f.IdColaborador
                                                  select new Formulario
                                                  {
                                                      Id = f.Id,
                                                      Matricula = c.Matricula,
                                                      Nome = c.Nome,
                                                      Funcao = c.Funcao,
                                                      Area = c.Area,
                                                      DtAdmissao = c.DataAdmissao == "" ? DateTime.Now.Date : Convert.ToDateTime(c.DataAdmissao),
                                                      GestorImediato = c.GestorImediato,
                                                      Criado = f.Criado,
                                                      IdColaborador = f.IdColaborador,
                                                      AprovacaoAuditoria = f.AprovacaoAuditoria,
                                                      AprovacaoGestor = f.AprovacaoGestor,
                                                      CriadoPor = f.CriadoPor,
                                                      Modificado = f.Modificado,
                                                      ModificadoPor = f.ModificadoPor,
                                                      Estagio = f.Estagio,
                                                      EstagioDesc = f.EstagioDesc,
                                                      AttachmentName = f.AttachmentName,
                                                      AttachmentUrl = f.AttachmentUrl,
                                                      NumeroFormulario = f.NumeroFormulario
                                                  })
                                                  .ToList();

                        return query;
                    }
                }
            }
            catch (Exception e)
            {
                throw (e);
            }
        }
        
        /// <summary>
        /// Recupera um formulário por colaborador.
        /// </summary>
        /// <param name="Employee">Colaborador</param>
        /// <returns></returns>
        public Formulario GetFormByEmployee(Colaborador Employee)
        {
            try
            {
                return GetAllForms().Where(p => p.IdColaborador == Employee.Id && p.Criado.Year == DateTime.Now.Year).SingleOrDefault();
            }
            catch (Exception e)
            {
                throw (e);
            }
        }

        public List<Formulario> GetAllFormsByYear()
        {
            return GetAllForms().Where(p => p.Criado.Year == DateTime.Now.Year).ToList();
        }

        public List<Formulario> GetFormsByStage(int idStage) 
        {
            return GetAllForms().Where(p => p.Estagio == idStage).ToList();
        }

        /// <summary>
        /// Recupera todos os formulários de um colaborador.
        /// </summary>
        /// <param name="Employee"></param>
        /// <returns></returns>
        public List<Formulario> GetFormsByEmployee(Colaborador Employee)
        {
            try
            {
                return GetAllForms().Where(p => p.IdColaborador == Employee.Id).ToList();
            }
            catch (Exception e)
            {
                throw (e);
            }
        }

        /// <summary>
        /// Recupera um formulário pelo Id do Colaborador.
        /// </summary>
        /// <param name="Id">Id do Colaborador</param>
        /// <returns></returns>
        public Formulario GetFormById(int Id)
        {
            try
            {
                return GetAllForms().Where(p => p.Id == Id).SingleOrDefault();
            }
            catch (Exception e)
            {
                throw (e);
            }
        }
        
        /// <summary>
        /// Define o estágio do formulário.
        /// </summary>
        /// <param name="idForm">Id do Formulário</param>
        /// <param name="idStage">Próximo estágio do formulário.</param>
        public void SetFormStage(int idForm, int idStage)
        {
            using (SPSite eSite = new SPSite(Site.ID))
            {
                using (SPWeb eWeb = eSite.OpenWeb(Web.ID))
                {
                    SPList Formulario = eWeb.Lists[ListaFormulario];
                    SPListItem item = Formulario.GetItemById(idForm);
                    item["Estagio"] = idStage;
                    item.Update();
                }
            }
        }
        
        /// <summary>
        /// Cria um novo formulário.
        /// </summary>
        /// <param name="Collaborator">Colaborador ao qual pertencerá o formulário.</param>
        public void CreateForm(Formulario form)
        {
            using (SPSite eSite = new SPSite(Site.ID))
            {
                using (SPWeb eWeb = eSite.OpenWeb(Web.ID))
                {
                    eWeb.AllowUnsafeUpdates = true;
                    SPListItemCollection listItems = eWeb.Lists[ListaFormulario].Items;

                    SPListItem item = listItems.Add();
                    item["IdColaborador"] = form.IdColaborador;
                    item["Estagio"] = form.Estagio;
                    item["NumeroFormulario"] = form.NumeroFormulario;

                    item.Update();
                    eWeb.AllowUnsafeUpdates = false;
                }
            }
        }
        
        /// <summary>
        /// Recupera todos os formulários de um gestor.
        /// </summary>
        /// <param name="idManager">Id do Gestor.</param>
        /// <returns></returns>
        public List<Formulario> GetSubordinateForms(int idManager)
        {
            /*Se necessário, fazer filtro pelo ano.*/
            return GetAllForms().Where(p => p.Estagio != 4 && Convert.ToInt32(p.GestorImediato.Split(new char[] {';'},StringSplitOptions.RemoveEmptyEntries)[0]) == idManager).ToList();
        }
        
        /// <summary>
        /// Recupera todos os formulários que estão no estágio da auditoria.
        /// </summary>
        /// <returns></returns>
        public List<Formulario> GetAuditForms()
        {
            return GetAllForms().Where(p => p.Estagio == 2 || p.Estagio == 1 || p.Estagio == 5).ToList();
        }
        
        /// <summary>
        /// Define se o formulário foi aprovacão ou devolvido por um gestor.
        /// </summary>
        /// <param name="form">Formulário a ser atualizado.</param>
        public void SetManagerApproval(Formulario form)
        {
            using (SPSite eSite = new SPSite(Site.ID))
            {
                using (SPWeb eWeb = eSite.OpenWeb(Web.ID))
                {
                    SPList Lista = eWeb.Lists[ListaFormulario];
                    SPListItem item = Lista.GetItemById(form.Id);
                    item["AprovacaoGestor"] = form.AprovacaoGestor;
                    item.Update();
                }
            }
        }
        
        /// <summary>
        /// Define se o formulário foi aprovacão ou devolvido pela auditoria.
        /// </summary>
        /// <param name="form">Formulário a ser atualizado.</param>
        public void SetAuditApproval(Formulario form)
        {
            using (SPSite eSite = new SPSite(Site.ID))
            {
                using (SPWeb eWeb = eSite.OpenWeb(Web.ID))
                {
                    SPList Lista = eWeb.Lists[ListaFormulario];
                    SPListItem item = Lista.GetItemById(form.Id);
                    item["AprovacaoGestor"] = form.AprovacaoGestor;
                    item["AprovacaoAuditoria"] = form.AprovacaoAuditoria;
                    item.Update();
                }
            }
        }

        /// <summary>
        /// Insere um anexo na lista.
        /// </summary>
        /// <param name="idItem">Id do item a anexar o item.</param>
        /// <param name="fileName">Nome do arquivo.</param>
        /// <param name="contents">Conteudo do fileUpload.</param>
        public void InsertAttachment(int idItem, string fileName, byte[] contents)
        {
            using (SPSite eSite = new SPSite(SPContext.Current.Site.ID))
            {
                using (SPWeb eWeb = eSite.OpenWeb(SPContext.Current.Web.ID))
                {
                    eWeb.AllowUnsafeUpdates = true;

                    SPList list = eWeb.Lists["Formulario"];
                    SPListItem newItem = list.GetItemById(idItem);

                    SPAttachmentCollection attachments = newItem.Attachments;
                    attachments.Add(fileName, contents);

                    newItem["AttachmentName"] = fileName;
                    newItem.Update();
                }
            }
        }

        /// <summary>
        /// Deleta um anexo da lista.
        /// </summary>
        /// <param name="idItem">Id do item onde se encontra o anexo a ser deletado.</param>
        public void DeleteAttachment(int idItem)
        {
            using (SPSite eSite = new SPSite(Site.ID))
            {
                using (SPWeb eWeb = eSite.OpenWeb(Web.ID))
                {
                    eWeb.AllowUnsafeUpdates = true;
                    SPList list = eWeb.Lists["Formulario"];
                    SPListItem delItem = list.GetItemById(idItem);

                    SPAttachmentCollection atCol = delItem.Attachments;

                    if (delItem["AttachmentName"] != null)
                    {
                        string strFileName = delItem["AttachmentName"].ToString();
                        delItem["AttachmentName"] = string.Empty;
                        atCol.Delete(strFileName);
                        delItem.Update();
                    }
                }
            }
        }
    }
}
